using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Documents;

namespace WozLib.UI.Ink.Adorners
{
  /// <summary>
  /// Shows a preview of the clients mouse cursor. The 
  /// </summary>
  public class ClientMouseAdorner : Adorner
  {

    SolidColorBrush _RenderBrush;
    Pen _RenderPen;

    RadialGradientBrush _RadialGradientBrush;
    Pen _GrayPen;
    Pen _BlackPen;
    Pen _PinkPen;
    Pen _GesturePen;
    Pen _SelectorPen;
    SolidColorBrush _BlueishBrush;

    PathGeometry _Eraser1;
    PathGeometry _Eraser2;
    PathGeometry _Eraser3;

    PathGeometry _Pencil1;
    PathGeometry _Pencil2;
    PathGeometry _Pencil3;

    PathGeometry _Gesture1;

    RectangleGeometry _Selector1;

    public Point PlacementCenterPoint
    {
      get { return _PlacementCenterPoint; }
      set { _PlacementCenterPoint = value; }
    } private Point _PlacementCenterPoint;

    public SketchPad.InkTools InkTool
    {
      get { return _InkTool; }
      set { _InkTool = value; }
    } private SketchPad.InkTools _InkTool;

    // Be sure to call the base class constructor.
    public ClientMouseAdorner(UIElement adornedElement, Point placementCenterPoint, SketchPad.InkTools inkTool)
      : base(adornedElement)
    {
      PlacementCenterPoint = placementCenterPoint;
      InkTool = inkTool;

      InitGraphics();
    }

    private void InitGraphics()
    {
      _RenderBrush = new SolidColorBrush(Colors.Green);
      _RenderPen = new Pen(new SolidColorBrush(Colors.Navy), 1.5);

      _RadialGradientBrush = new RadialGradientBrush(Colors.AliceBlue, Color.FromScRgb(1.0F, 0.2725F, 0.3353F, 0.7882F));
      _RadialGradientBrush.GradientOrigin = new Point(0, 0);
      _RadialGradientBrush.RadiusX = 1;
      _RadialGradientBrush.RadiusY = 1;
      _RadialGradientBrush.Center = new Point(0, 0);

      _BlueishBrush = new SolidColorBrush(Color.FromScRgb(1.0F, 0.2725F, 0.3353F, 0.7882F));

      // some pens uses brushes above
      _GrayPen = new Pen(new SolidColorBrush(Colors.Gray), 0.5);
      _BlackPen = new Pen(new SolidColorBrush(Colors.Black), 0.5);
      _PinkPen = new Pen(new SolidColorBrush(Colors.Pink), 0.5);
      _GesturePen = new Pen(_BlueishBrush, 1);
      _GesturePen.DashStyle = DashStyles.Dash; // new DashStyle(new double[] { 2, 1 }, 0);
      _SelectorPen = new Pen(Brushes.Black, 1);
      _SelectorPen.DashStyle = DashStyles.Dash;

      // Eraser
      PathFigure eraserFigure1 = new PathFigure();
      eraserFigure1.StartPoint = new Point(0, 0);
      eraserFigure1.Segments.Add(new LineSegment(new Point(6, 0), true));
      eraserFigure1.Segments.Add(new LineSegment(new Point(12, 8), true));
      eraserFigure1.Segments.Add(new LineSegment(new Point(6, 8), true));
      eraserFigure1.Segments.Add(new LineSegment(new Point(0, 0), true));
      _Eraser1 = new PathGeometry();
      _Eraser1.Figures.Add(eraserFigure1);

      PathFigure eraserFigure2 = new PathFigure();
      eraserFigure2.StartPoint = new Point(12, 8);
      eraserFigure2.Segments.Add(new LineSegment(new Point(6, 8), true));
      eraserFigure2.Segments.Add(new LineSegment(new Point(6, 12), true));
      eraserFigure2.Segments.Add(new LineSegment(new Point(12, 12), true));
      eraserFigure2.Segments.Add(new LineSegment(new Point(12, 8), true));
      _Eraser2 = new PathGeometry();
      _Eraser2.Figures.Add(eraserFigure2);

      PathFigure eraserFigure3 = new PathFigure();
      eraserFigure3.StartPoint = new Point(0, 0);
      eraserFigure3.Segments.Add(new LineSegment(new Point(6, 8), true));
      eraserFigure3.Segments.Add(new LineSegment(new Point(6, 12), true));
      eraserFigure3.Segments.Add(new LineSegment(new Point(0, 4), true));
      eraserFigure3.Segments.Add(new LineSegment(new Point(0, 0), true));
      _Eraser3 = new PathGeometry();
      _Eraser3.Figures.Add(eraserFigure3);

      // Pencil
      PathFigure pencilFigure1 = new PathFigure();
      pencilFigure1.StartPoint = new Point(2, 4);
      pencilFigure1.Segments.Add(new LineSegment(new Point(4, 2), true));
      pencilFigure1.Segments.Add(new LineSegment(new Point(10, 8), true));
      pencilFigure1.Segments.Add(new LineSegment(new Point(8, 10), true));
      pencilFigure1.Segments.Add(new LineSegment(new Point(2, 4), true));
      _Pencil1 = new PathGeometry();
      _Pencil1.Figures.Add(pencilFigure1);

      PathFigure pencilFigure2 = new PathFigure();
      pencilFigure2.StartPoint = new Point(8, 10);
      pencilFigure2.Segments.Add(new LineSegment(new Point(10, 8), true));
      pencilFigure2.Segments.Add(new LineSegment(new Point(12, 12), true));
      pencilFigure2.Segments.Add(new LineSegment(new Point(8, 10), true));
      _Pencil2 = new PathGeometry();
      _Pencil2.Figures.Add(pencilFigure2);

      PathFigure pencilFigure3 = new PathFigure();
      pencilFigure3.StartPoint = new Point(2, 4);
      pencilFigure3.Segments.Add(new LineSegment(new Point(0, 2), true));
      pencilFigure3.Segments.Add(new LineSegment(new Point(2, 0), true));
      pencilFigure3.Segments.Add(new LineSegment(new Point(4, 2), true));
      pencilFigure3.Segments.Add(new LineSegment(new Point(2, 4), true));
      _Pencil3 = new PathGeometry();
      _Pencil3.Figures.Add(pencilFigure3);

      // Gesture
      PathFigure gestureFigure1 = new PathFigure();
      gestureFigure1.StartPoint = new Point(1, 11);
      gestureFigure1.Segments.Add(new BezierSegment(new Point(15,4),new Point(8,0), new Point(2,4),true));
      gestureFigure1.Segments.Add(new BezierSegment(new Point(3, 11), new Point(11, 11), new Point(11, 11), true));
      _Gesture1 = new PathGeometry();
      _Gesture1.Figures.Add(gestureFigure1);

      // Selector
      _Selector1 = new RectangleGeometry(new Rect(0, 2, 12, 10));
    }

    // A common way to implement an adorner's rendering behavior is to override the OnRender
    // method, which is called by the layout subsystem as part of a rendering pass.
    protected override void OnRender(DrawingContext drawingContext)
    {
      // Some arbitrary drawing implements.
      _RenderBrush.Opacity = 0.2;
      double renderRadius = 5.0;
      

      switch (InkTool)
      {
        case SketchPad.InkTools.Pencil:
          drawingContext.PushTransform(new TranslateTransform(_PlacementCenterPoint.X - 12, _PlacementCenterPoint.Y - 12));
          drawingContext.DrawGeometry(Brushes.Yellow, _GrayPen, _Pencil1);
          drawingContext.DrawGeometry(Brushes.Black, _BlackPen, _Pencil2);
          drawingContext.DrawGeometry(Brushes.Pink, _PinkPen, _Pencil3);
          break;
        case SketchPad.InkTools.Eraser:
          drawingContext.PushTransform(new TranslateTransform(_PlacementCenterPoint.X - 12, _PlacementCenterPoint.Y - 12));
          drawingContext.DrawGeometry(_RadialGradientBrush, _GrayPen, _Eraser1);
          drawingContext.DrawGeometry(_BlueishBrush, _GrayPen, _Eraser2);
          drawingContext.DrawGeometry(_RadialGradientBrush, _GrayPen, _Eraser3);
          break;
        case SketchPad.InkTools.Selector:
          drawingContext.PushTransform(new TranslateTransform(_PlacementCenterPoint.X - 12, _PlacementCenterPoint.Y - 12));
          drawingContext.DrawGeometry(Brushes.Transparent, _SelectorPen, _Selector1);
          break;
        case SketchPad.InkTools.Gesture:
          drawingContext.PushTransform(new TranslateTransform(_PlacementCenterPoint.X - 12, _PlacementCenterPoint.Y - 12));
          drawingContext.DrawGeometry(Brushes.Transparent, _GesturePen, _Gesture1);
          break;
        case SketchPad.InkTools.None:
          drawingContext.DrawEllipse(_RenderBrush, _RenderPen, PlacementCenterPoint, renderRadius, renderRadius);
          break;
        default:
          drawingContext.DrawEllipse(_RenderBrush, _RenderPen, PlacementCenterPoint, renderRadius, renderRadius);
          break;
      }
      
    }
  }
}
